<template>
  <Card class="announcement" :bordered="false">
    <template #title> 公告列表 （{{ announcement.pagination?.total ?? '-' }}） </template>
    <template #extra>
      <Button type="primary" size="small" @click="createNewData">
        <PlusOutlined />发布新公告
      </Button>
    </template>
    <Space class="toolbar">
      <Space>
        <Select
          :loading="loading.state.value"
          class="select"
          v-model:value="filterParams.state"
          @change="handleChange"
        >
          <SelectOption :value="SELECT_ALL_VALUE">全部状态</SelectOption>
          <SelectOption :value="0">
            <Space> <EditOutlined />草稿 </Space>
          </SelectOption>
          <SelectOption :value="1">
            <Space> <CheckOutlined />已发布 </Space>
          </SelectOption>
        </Select>
        <InputSearch
          class="search"
          placeholder="输入关键词搜索"
          :loading="loading.state.value"
          v-model:value="filterParams.keyword"
          @search="handleSearch"
        />
        <Button type="primary" :loading="loading.state.value" @click="resetParamsAndRefresh">
          <template #icon>
            <ReloadOutlined />
          </template>
          重置并刷新
        </Button>
      </Space>
      <Space>
        <Button type="primary" :disabled="!selectedIDs.length" @click="handleDeleteList">
          <template #icon>
            <DeleteOutlined />
          </template>
          批量删除
        </Button>
      </Space>
    </Space>
    <Divider />
    <Spin :spinning="loading.state.value">
      <Table
        :data-source="announcement.data"
        rowKey="_id"
        :row-selection="{
          selectedRowKeys: selectedIDs,
          onChange: handleSelect,
        }"
        :pagination="{
          current: announcement.pagination?.current_page,
          pageSize: announcement.pagination?.per_page,
          total: announcement.pagination?.total,
          showSizeChanger: true,
        }"
        @change="handlePaginate"
      >
        <TableColumn key="id" :width="60" title="ID" data-index="id"></TableColumn>
        <TableColumn key="content" title="内容" data-index="content"></TableColumn>
        <TableColumn key="create_at" :width="180" title="发布时间" data-index="create_at">
          <template #default="{ record }">{{ stringToYMD(record.create_at) }}</template>
        </TableColumn>
        <TableColumn key="state" :width="120" title="状态" data-index="state">
          <template #default="{ record }">
            <Tag :color="ps(record.state).color">
              <template #icon>
                <component :is="ps(record.state).icon" />
              </template>
              {{ ps(record.state).name }}
            </Tag>
          </template>
        </TableColumn>
        <TableColumn key="action" :width="160" title="操作" data-index="action">
          <template #default="{ record, index }">
            <ButtonGroup>
              <Button size="small" type="text" @click="editData(index)">
                <template #icon>
                  <EditOutlined />
                </template>
                编辑
              </Button>
              <Button size="small" type="text" :danger="true" @click="handleDelete(record._id)">
                <template #icon>
                  <DeleteOutlined />
                </template>
                删除
              </Button>
            </ButtonGroup>
          </template>
        </TableColumn>
      </Table>
    </Spin>
    <EditModal
      :title="activeEditData ? '编辑公告' : '新公告'"
      :visible="isVisibleModal"
      :announcement="activeEditData"
      :onCancel="closeModal"
      :onSubmit="handleSubmit"
    />
  </Card>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted } from 'vue'
import {
  Button,
  ButtonGroup,
  Card,
  Divider,
  InputSearch,
  Modal,
  Select,
  SelectOption,
  Space,
  Spin,
  Table,
  TableColumn,
  TablePaginationConfig,
  Tag,
} from 'ant-design-vue'
import {
  PlusOutlined,
  EditOutlined,
  CheckOutlined,
  DeleteOutlined,
  ReloadOutlined,
} from '@ant-design/icons-vue'

import type { Announcement as AnnouncementType } from '@/constants/announcement'
import type { ResponsePaginationData } from '@/constants/request'
import EditModal from './editModal.vue'
import { stringToYMD } from '@/transformers/date'
import {
  getAnnouncements,
  deleteAnnouncement,
  deleteAnnouncements,
  putAnnouncement,
  createAnnouncement,
} from '@/store/announcement'
import type { GetAnnouncementsParams } from '@/store/announcement'
import { PublishState, ps } from '@/constants/publish'
import { useLoading } from '@/handcer'

const loading = useLoading()

// 列表数据
const announcement = reactive<ResponsePaginationData<AnnouncementType>>({
  data: [],
  pagination: undefined,
})

const SELECT_ALL_VALUE = 'ALL'

// 多选
const selectedIDs = ref<Array<string>>([])
const handleSelect = (ids: any[]) => {
  selectedIDs.value = ids
}

// 过滤参数
const filterParams = reactive({
  state: SELECT_ALL_VALUE as typeof SELECT_ALL_VALUE | PublishState,
  keyword: '',
})

// 弹窗
const activeEditDataIndex = ref<number | null>(null)
const isVisibleModal = ref<boolean>(false)
const activeEditData = computed(() => {
  const index = activeEditDataIndex.value
  return index !== null ? announcement.data[index] : null
})
const closeModal = () => {
  isVisibleModal.value = false
}

// 编辑创建
const editData = (index: number) => {
  activeEditDataIndex.value = index
  isVisibleModal.value = true
}
const createNewData = () => {
  activeEditDataIndex.value = null
  isVisibleModal.value = true
}

const handleSearch = () => {
  fetchData()
}

const fetchData = (params?: GetAnnouncementsParams) => {
  const getParams: GetAnnouncementsParams = {
    ...params,
    state: filterParams.state !== SELECT_ALL_VALUE ? filterParams.state : undefined,
    keyword: filterParams.keyword ? filterParams.keyword : undefined,
  }
  loading.promise(getAnnouncements(getParams)).then((response) => {
    announcement.data = response.data
    announcement.pagination = response.pagination
  })
}

const resetParamsAndRefresh = () => {
  filterParams.keyword = ''
  if (filterParams.state === SELECT_ALL_VALUE) {
    fetchData()
  } else {
    filterParams.state = SELECT_ALL_VALUE
  }
}

// 翻页
const handlePaginate = (pagination: TablePaginationConfig) => {
  const { current, pageSize } = pagination
  fetchData({ page: current, per_page: pageSize })
}

const handleChange = () => {
  fetchData()
}

// 重新刷新数据
const refreshData = () => {
  fetchData({
    page: announcement.pagination?.current_page,
    per_page: announcement.pagination?.per_page,
  })
}

// 单个删除
const handleDelete = (id: string) => {
  Modal.confirm({
    title: '确定要删除公告吗？',
    content: '删除后不可恢复',
    centered: true,
    onOk: () => {
      deleteAnnouncement(id).then(() => {
        refreshData()
      })
    },
  })
}

// 批量删除
const handleDeleteList = () => {
  const ids = selectedIDs.value
  Modal.confirm({
    title: `确定要删除 ${ids.length} 个公告吗？`,
    content: '删除后不可恢复',
    centered: true,
    onOk: () => {
      deleteAnnouncements(ids).then(() => {
        refreshData()
      })
    },
  })
}

// 提交表单
const handleSubmit = (announcement: AnnouncementType) => {
  if (activeEditData.value) {
    putAnnouncement({
      ...activeEditData.value,
      ...announcement,
    }).then(() => {
      closeModal()
      refreshData()
    })
  } else {
    createAnnouncement(announcement).then(() => {
      closeModal()
      refreshData()
    })
  }
}

onMounted(() => {
  fetchData()
})
</script>

<style lang="less" scoped>
.announcement {
  .toolbar {
    display: flex;
    justify-content: space-between;

    .select {
      width: 130px;
    }
    .search {
      width: 200px;
    }
  }
}
</style>
